package cn.infrabase;

/**
 * 断言工具类。
 *
 * @author Weimin Gao
 * @since 1.0.0
 **/
public class Assert {

    /**
     * 断言给定的参数值不为null值。
     *
     * @param parameter 参数名称。
     * @param value     参数值。
     * @param <T>       参数值的类型。
     * @throws AssertException 如果给定参数值为null时。
     */
    public static <T> T notNull(String parameter, T value) throws AssertException {
        if (value == null) {
            throw new AssertException(String.format("参数【%s】不可以为null值", parameter));
        }
        return value;
    }

    /**
     * 断言给定的参数值不为null值和空白字符。
     *
     * @param parameter 参数名称。
     * @param value     参数值。
     * @param <T>       参数值的类型。
     * @throws AssertException 如果给定参数值为null或空白字符时。
     */
    public static <T> T notBlank(String parameter, T value) throws AssertException {
        if (value == null || isBlank(value.toString())) {
            throw new AssertException(String.format("参数【%s】不可以为null值和空白字符", parameter));
        }
        return value;
    }

    /**
     * 断言给定的表达式计算结果为真。
     *
     * @param expression 表达式。
     * @param value      表达式计算结果。
     * @throws AssertException 如果给定表达式计算结果为假（false）时。
     */
    public static void isTrue(String expression, boolean value) throws AssertException {
        if (!value) {
            throw new AssertException(String.format("表达式【%s】计算结果必须为真", expression));
        }
    }

    /**
     * 断言给定的表达式计算结果为假。
     *
     * @param expression 表达式。
     * @param value      表达式计算结果。
     * @throws AssertException 如果给定表达式计算结果为真（true）时。
     */
    public static void isFalse(String expression, boolean value) throws AssertException {
        if (value) {
            throw new AssertException(String.format("表达式【%s】计算结果必须为假", expression));
        }
    }

	// -----------------------------------------------------------------------------------------------------------------

	private static boolean isBlank(CharSequence cs) {
		if (cs != null) {
			int length = cs.length();
			for (int i = 0; i < length; i++) {
				if (!isBlankChar(cs.charAt(i))) {
					return false;
				}
			}
		}
		return true;
	}

	private static boolean isBlankChar(int c) {
		return Character.isWhitespace(c)
			|| Character.isSpaceChar(c)
			|| c == '\ufeff'
			|| c == '\u202a'
			|| c == '\u0000';
	}
}
